package com.gxaedu.rbac.interceptor;

import com.gxaedu.rbac.exception.RbacException;
import com.gxaedu.rbac.pojo.Auth;
import com.gxaedu.rbac.pojo.Role;
import com.gxaedu.rbac.pojo.User;
import com.gxaedu.rbac.service.RbacService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;

/**
 * 权限拦截器
 * @author:Teacher黄
 * @date:Created at 2020/04/22
 */
public class RbacInterceptor implements HandlerInterceptor {


    @Autowired
    private RbacService rbacService;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        /**
         * 可以优化, 借助redis来优化
         * 1. 判断是否是超级管理员的结果, 可以存储到reids
         * 2. 当前登陆用户所拥有的权限可以存储到redis中
         * 3. 退出登陆之后 干掉保存的数据
         */
        // 1. 判断当前用户的角色
        if (rbacService.redisIsSuper(request)) {
            // 放行
            return true;
        }
        // 2. 获取当前登陆用户的权限
        List<Auth> authList = rbacService.redisAuthList(request);

        // 3. 判断当前用户是否有对应的权限
        // 如何判断?
        if (hasAuth(request,authList)) {
            return true;
        }
        // 抛出没有权限的异常
        throw new RbacException(9527,"对不起,你没有该权限!");
    }





    /**
     * 判断是否有对应的权限
     * @param request
     * @param auths
     * @return
     */
    private Boolean hasAuth(HttpServletRequest request, List<Auth> auths){
        // 先去获取访问的URI
        String authUrl = request.getRequestURI();
        // 再去通过authUrl 和 auths 进行一个比对
        // 如果 authUrl在auth这个list中 , 说明有权限, 如果不在说明没有权限
        for (Auth auth : auths) {
            // 排除父级权限
            if (auth.getAuthUrl() == null || auth.getAuthUrl().isEmpty()) {
                continue;
            }
            // 比对
            if (auth.getAuthUrl().equals(authUrl)) {
                return true;
            }
        }
        return false;
    }


    /**
     * 判断是否是超级管理员
     * @param user
     * @return
     */
    private Boolean isSuper(User user){
        List<Role> roles = user.getRoles();
        if (roles.size() == 0) {
            // 用户如果没有角色,那么就不是超级管理员
            return false;
        }
        // 遍历判断是否是超级管理员
        for (Role role : roles) {
            if (role.getIsSuper().equals(1L)) {
                return true;
            }
        }
        return false;
    }


    /**
     * 获取认证的权限列表
     * @param user
     * @return
     */
    private List<Auth> getAuthList(User user){
        // 准备一个装权限的list
        List<Auth> auths = new ArrayList<>();
        // 1. 先获取角色
        List<Role> roles = user.getRoles();
        if(roles.size() == 0){
            return null;
        }
        // 依次的去对应角色下面获取对应的权限
        for (Role role : roles) {
            auths.addAll(role.getAuths());
        }
        return auths;
    }
}
